package com.gsbelarus.gedemin.salary.util;

import android.util.Log;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

public class SOAPWebServiceManager {

    private static final String SOAP_DATE_FORMAT = "yyyy-MM-dd";
    private static final String SOAP_REQUEST =
            "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
                    "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
                    "   <soap:Body>" +
                    "       <%s xmlns=\"%s\">" +    // [1]METHOD_NAME [2]NAMESPACE
                    "           %s " +              // [3]PROPERTIES
                    "       </%s>" +                // [4]METHOD_NAME
                    "   </soap:Body>" +
                    "</soap:Envelope>";

    private static String makeRequestEnvelope(String methodName, String namespace, String properties) {
        return String.format(SOAP_REQUEST, methodName, namespace, properties, methodName);
    }

    public static String soapFormatDate(Date date) {
        return new SimpleDateFormat(SOAP_DATE_FORMAT).format(date) + "T00:00:00";
    }

    public static String call(String serviceUrl, String soapAction,
                              String methodName, String namespace, String properties) {  //TODO StringBuilder
        String requestEnvelope = makeRequestEnvelope(methodName, namespace, properties);
        String responseString = null;

        WebServiceManager webServiceManager = new WebServiceManager();
        Map<String, String> headers = new HashMap<>();
        headers.put("Connection", "close");  // disable keep-alive
        headers.put("Content-Type", "application/json; charset=utf-8");
        headers.put("SOAPAction", soapAction);

        try {
            webServiceManager.openConnection(serviceUrl);
            // do {
            webServiceManager.sendPostRequest(requestEnvelope.getBytes(), headers);
            //} while (responseCode == -1);

            if (webServiceManager.hasResponseStatusOK())
                responseString = webServiceManager.getResponse();

            Log.d("my", responseString);

            return responseString;
        } catch (IOException e) {
            //Crashlytics.getInstance().core.logException(e);
            e.printStackTrace();
            Log.e("SOAPWebServiceManager", "error " + e.toString());

            return null;
        } finally {
            webServiceManager.closeConnection();
        }
    }

    public static String parseResponse(String searchXPath, String responseEnvelope) {
        Document msgXML = null;
        try {
            msgXML = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(responseEnvelope)));
        } catch (SAXException | ParserConfigurationException | IOException e) {
            //Crashlytics.getInstance().core.logException(e);
            e.printStackTrace();
        }
        // создать объект XPath
        XPath xpath = XPathFactory.newInstance().newXPath();
        // выполнить поиск по xpath-выражению в строке
        try {
            return xpath.evaluate(searchXPath, msgXML);
        } catch (XPathExpressionException e) {
            //Crashlytics.getInstance().core.logException(e);
            e.printStackTrace();
        }

        return null;
    }
}
